package net.sansi.v3correctserver.service.space;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.spring.SpringUtil;
import lombok.Getter;
import lombok.Setter;
import net.sansi.v3correctserver.constenum.FilenameGenerator;
import net.sansi.v3correctserver.entity.screen.Screen;
import net.sansi.v3correctserver.entity.space.CorrectCnf;
import net.sansi.v3correctserver.entity.space.ProjectSpaceCnf;
import net.sansi.v3correctserver.service.screen.ScreenService;
import net.sansi.v3correctserver.util.JacksonUtil;
import net.sansi.v3correctserver.util.LocalCache;
import net.sansi.v3correctserver.util.SpaceUtil;

import java.nio.file.Path;
import java.util.List;

/**
 * Created by Fang
 * create time : 2025/1/22
 * IDE : IntelliJ IDEA
 * <p>
 * 项目空间
 */

@Getter
@Setter
public class ProjectSpace extends SpaceUtil {

    private ProjectSpaceCnf config;

    public ProjectSpace(ProjectSpaceCnf config) {
        super(config.getSpacePath());
        this.config = config;
    }

    /**
     * 亮度矫正文件夹
     *
     * @return 亮度矫正空间
     */
    public SpaceUtil brightCorrectSpace() {
        return config.getSpaceUtil().createDir("bright_correct", true);
    }

    /**
     * 色度矫正文件夹
     *
     * @return 色度矫正空间
     */
    public SpaceUtil chromaCorrectSpace() {
        return config.getSpaceUtil().createDir("chroma_correct", true);
    }

    /**
     * 分析相片目录
     *
     * @return 分析相片目录
     */
    public SpaceUtil analyseSpace() {
        return config.getSpaceUtil().createDir("analyse", true);
    }

    /**
     * 系数文件夹
     *
     * @return 系数文件夹
     */
    public SpaceUtil factorSpace() {
        return config.getSpaceUtil().createDir("factor", true);
    }


    // 矫正配置缓存
    private static final LocalCache<CorrectCnf> correctCnfLocalCache = new LocalCache<>();

    /**
     * 保存矫正配置
     *
     * @param cnf 矫正配置
     */
    public synchronized void saveCorrectCnf(CorrectCnf cnf) {
        FileUtil.writeUtf8String(
                JacksonUtil.toPrettyString(cnf),
                correctCnfPath().toFile()
        );
        correctCnfLocalCache.put(getConfig().getName(), cnf);
    }

    /**
     * 获取矫正配置
     *
     * @return 矫正配置
     */
    public CorrectCnf getCorrectCnf() {
        return correctCnfLocalCache.get(getConfig().getName(), () -> {
            if (!correctCnfPath().toFile().exists()) {
                saveCorrectCnf(new CorrectCnf());
            }
            return JacksonUtil.readValue(
                    FileUtil.readUtf8String(correctCnfPath().toFile()),
                    CorrectCnf.class
            );
        });
    }

    /**
     * 获取矫正配置路径
     *
     * @return 矫正配置路径
     */
    public Path correctCnfPath() {
        return config.getSpaceUtil().resolveFilename(CorrectCnf.FILE_NAME);
    }

    // 显示屏 缓存
    public static final LocalCache<Screen> screenCache = new LocalCache<>();

    /**
     * 获取显示屏信息
     * 带scanBoards
     *
     * @param screenId    显示屏 id
     * @param ignoreCache 是否忽略缓存
     * @return 屏幕配置
     */
    public Screen getScreen(String screenId, boolean ignoreCache) {
        return screenCache.get(screenId, () -> {
            ScreenService screenService = SpringUtil.getBean(ScreenService.class);
            List<Screen> list = screenService.list();
            Screen one = CollUtil.findOne(list, s -> s.getId().equals(screenId));
            one.setScanBoards(screenService.scanBoards(one.getId()));
            return one;
        }, ignoreCache);
    }

    /**
     * 获取显示屏信息
     * 带scanBoards
     * screenId 来自correctCnf
     *
     * @return 屏幕配置
     */
    public Screen getScreen(boolean ignoreCache) {
        return getScreen(getCorrectCnf().getScreenId(), ignoreCache);
    }


    /**
     * 分析用黑色背景
     *
     * @param areaId   区域
     * @param colorIdx 颜色索引
     * @return
     */
    public Path analyseBlackPhoto(int areaId, int colorIdx) {
        CorrectCnf correctCnf = getCorrectCnf();
        return analyseSpace().resolveFilename(
                FilenameGenerator.blackPhoto(
                        correctCnf.getCamera(),
                        areaId, colorIdx
                )
        );
    }

    /**
     * 分析用围栏照片
     *
     * @param areaId   区域
     * @param colorIdx 颜色索引
     * @return 分析用围栏照片
     */
    public Path analyseFenceFullPhoto(int areaId, int colorIdx) {
        CorrectCnf correctCnf = getCorrectCnf();
        return analyseSpace().resolveFilename(
                FilenameGenerator.fullPhoto(
                        correctCnf.getCamera(),
                        colorIdx, areaId
                )
        );
    }

    /**
     * 分析相片
     *
     * @param areaId   区域id
     * @param colorIdx 颜色索引
     * @return 分析相片
     */
    public Path analysePhoto(int areaId, int colorIdx) {
        CorrectCnf correctCnf = getCorrectCnf();
        return analyseSpace().resolveFilename(
                FilenameGenerator.analysePhoto(
                        correctCnf.getCamera(),
                        correctCnf.getCameraParams().get(colorIdx),
                        colorIdx, areaId
                )
        );
    }

    /**
     * 亮度矫正用黑色背景照片
     *
     * @param areaId   区域id
     * @param colorIdx 颜色索引
     * @return 黑色背景照片
     */
    public Path brightBlackPhoto(int areaId, int colorIdx) {
        return brightCorrectSpace().resolveFilename(
                FilenameGenerator.blackPhoto(
                        getCorrectCnf().getCamera(),
                        areaId, colorIdx
                )
        );
    }

    /**
     * 亮度矫正相片
     *
     * @param areaId    区域id
     * @param colorIdx  颜色id
     * @param ofx       x 偏移
     * @param ofy       y 偏移
     * @param lowBright 是否低亮度
     * @return 亮度矫正相片
     */
    public Path brightPhoto(int areaId, int colorIdx, int ofx, int ofy, boolean lowBright) {
        CorrectCnf correctCnf = getCorrectCnf();
        return brightCorrectSpace().resolveFilename(
                FilenameGenerator.brightPhoto(
                        correctCnf.getCamera(),
                        areaId, colorIdx, ofx, ofy,
                        lowBright ? 1 : 0
                )
        );
    }

    /// 以下为亮度矫正相关文件路径快速获取方式

    /**
     * 亮度矫正结果
     *
     * @param areaId   区域id
     * @param colorIdx 颜色索引
     * @return 亮度矫正结果
     */
    public Path brightResult(int areaId, int colorIdx) {
        return brightCorrectSpace().resolveFilename(
                FilenameGenerator.brightResult(
                        areaId, colorIdx
                )
        );
    }

    /**
     * 亮度矫正结果预览
     *
     * @param areaId   区域id
     * @param colorIdx 颜色索引
     * @return 亮度矫正结果预览
     */
    public Path brightResultPreview(int areaId, int colorIdx) {
        return brightCorrectSpace().resolveFilename(
                FilenameGenerator.brightResultPreview(
                        areaId, colorIdx
                )
        );
    }

    /**
     * 亮度矫正结果展示（打屏用）
     *
     * @param areaId   区域id
     * @param colorIdx 颜色索引
     * @return 打屏相片
     */
    public Path brightResultShow(int areaId, int colorIdx) {
        return brightCorrectSpace().resolveFilename(
                FilenameGenerator.brightResultShow(
                        areaId, colorIdx
                )
        );
    }

    /**
     * 亮度矫正结果展示（标准用）
     *
     * @param areaId   区域id
     * @param colorIdx 颜色索引
     * @return 标准色度矫正结果展示（打屏用）
     */
    public Path brightResultShowStd(int areaId, int colorIdx) {
        return brightCorrectSpace().resolveFilename(
                FilenameGenerator.brightResultShowStd(
                        areaId, colorIdx
                )
        );
    }

    /**
     * 亮度矫正亮暗线矫正结果
     *
     * @param areaId   区域id
     * @param colorIdx 颜色索引
     * @return 亮暗线矫正结果
     */
    public Path brightLineCorrectResult(int areaId, int colorIdx) {
        return brightCorrectSpace().resolveFilename(
                FilenameGenerator.brightLineCorrectResult(
                        areaId, colorIdx
                )
        );
    }

    /**
     * 亮度矫正边框相片
     *
     * @param areaId   区域id
     * @param colorIdx 颜色索引
     * @return 边框矩阵
     */
    public Path borderResult(int areaId, int colorIdx) {
        return brightCorrectSpace().resolveFilename(
                FilenameGenerator.borderResult(
                        areaId, colorIdx
                )
        );
    }

    /**
     * 亮度矫正融合后的结果
     *
     * @param colorIdx 颜色索引
     * @return 路径
     */
    public Path brightMergeResult(int colorIdx, boolean fixLine) {
        return brightCorrectSpace().resolveFilename(
                FilenameGenerator.brightMergeResult(
                        colorIdx, fixLine
                )
        );
    }

    /**
     * 亮度矫正融合后的结果展示（打屏用）
     *
     * @param colorIdx 颜色索引
     * @return 路径
     */
    public Path brightMergeShow(int colorIdx, boolean fixLine) {
        return brightCorrectSpace().resolveFilename(
                FilenameGenerator.brightMergeShow(
                        colorIdx, fixLine
                )
        );
    }


    /**
     * 色度矫正相片
     *
     * @param areaId   区域id
     * @param colorIdx 颜色索引
     * @param ofx      x 偏移
     * @param ofy      y 偏移
     * @return 图片地址
     */
    public Path chromaPhoto(int areaId, int colorIdx, int ofx, int ofy) {
        return chromaCorrectSpace().resolveFilename(
                FilenameGenerator.chromaPhoto(
                        getCorrectCnf().getCamera(),
                        areaId, colorIdx, ofx, ofy
                )
        );
    }

    /**
     * 色度矫正结果
     *
     * @param areaId   区域id
     * @param colorIdx 颜色索引
     * @return 色度矫正结果
     */
    public Path chromaResult(int areaId, int colorIdx) {
        return chromaCorrectSpace().resolveFilename(
                FilenameGenerator.chromaResult(
                        areaId, colorIdx
                )
        );
    }

    /**
     * 色度矫正结果预览
     *
     * @param areaId   区域id
     * @param colorIdx 颜色索引
     * @return 色度矫正结果预览
     */
    public Path chromaResultPreview(int areaId, int colorIdx) {
        return chromaCorrectSpace().resolveFilename(
                FilenameGenerator.chromaResultPreview(
                        areaId, colorIdx
                )
        );
    }

    /**
     * 色度矫正结果展示（打屏用）
     *
     * @param areaId   区域id
     * @param colorIdx 颜色索引
     * @return 打屏相片
     */
    public Path chromaResultShow(int areaId, int colorIdx) {
        return chromaCorrectSpace().resolveFilename(
                FilenameGenerator.chromaResultShow(
                        areaId, colorIdx
                )
        );
    }

    /**
     * cl系数文件路径
     * 面板系数
     *
     * @param panelId 面板索引
     * @return cl系数文件路径
     */
    public Path factorCL(String panelId) {
        return factorSpace().resolveFilename(
                FilenameGenerator.factorCL(panelId)
        );
    }

    /**
     * cl zip系数文件路径
     *
     * @return 文件路径
     */
    public Path factorCLZip() {
        return factorSpace().resolveFilename(
                FilenameGenerator.factorCLZip()
        );
    }

    /**
     * cf系数文件路径
     * 扫描板系数
     *
     * @param scanBoardId 扫描板id
     * @return cf 系数文件
     */
    public Path factorCF(String scanBoardId) {
        return factorSpace().resolveFilename(
                FilenameGenerator.factorCF(scanBoardId)
        );
    }

    /**
     * CF zip 系数文件路径
     *
     * @return 文件路径
     */
    public Path factorCFZip() {
        return factorSpace().resolveFilename(
                FilenameGenerator.factorCFZip()
        );
    }

}
